package com.hyzh.latte.vehicle.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.coffee.core.CoffeeException;
import com.coffee.core.CoffeePage;
import com.coffee.core.CoffeeResponse;
import com.coffee.core.CoffeeResponseEnum;
import com.hyzh.latte.util.LatteResponseCode;
import com.hyzh.latte.util.StringKits;
import com.hyzh.latte.util.gather.OkhttpUtil;
import com.hyzh.latte.vehicle.dmo.*;
import com.hyzh.latte.vehicle.dmo.entity.ParkPGEntity;
import com.hyzh.latte.vehicle.dmo.entity.VehicleTrackRecordPGEntity;
import com.hyzh.latte.vehicle.nezha.NezhaDeviceManager;
import com.hyzh.latte.vehicle.nezha.NezhaPersonManager;
import com.hyzh.latte.vehicle.nezha.ParkDeviceBuilder;
import com.hyzh.latte.vehicle.service.NezhaRecordService;
import com.hyzh.latte.vehicle.service.VehicleTrackService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author songkui
 * @since 2024/4/12 19:08
 */
@RestController
@RequestMapping("/history")
@Slf4j
@AllArgsConstructor
//@CrossOrigin
public class HistoryTrackController {


    private final NezhaRecordService nezhaRecordService;

    private final VehicleTrackService vehicleTrackService;

    //通过摄像头编号 查询 该摄像头下面的车辆信息
    @GetMapping("/enterprise-camera")
    public CoffeeResponse<List<VehicleTrackCameraVO>> enterpriseCamera(@RequestHeader("park") String park,
                                                      @RequestParam(name = "cno", required = false) String cno,
                                                      @RequestParam(name = "vno", required = false) String vno,
                                                      @RequestParam(name = "start") String start,
                                                      @RequestParam(name = "end") String end) {

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime startDateTime = LocalDateTime.parse(start, formatter);
        LocalDateTime endDateTime = LocalDateTime.parse(end, formatter);
        long days = startDateTime.until(endDateTime, ChronoUnit.DAYS);
        if (days > 15) {
            return CoffeeResponse.responseMessage(CoffeeResponseEnum.ParamInvalid.code(), "时间间隔不能大于15天");
        }

        List<VehicleTrackCameraVO> listVno = nezhaRecordService.enterpriseCamera(park, cno, vno, startDateTime, endDateTime);
        if (CollectionUtil.isEmpty(listVno)) {
            return CoffeeResponse.response(LatteResponseCode.ExcelNotData);
        }

        log.info("enterprise-camera:   park {}, list size: {}", park, listVno.size());
        return CoffeeResponse.responseSuccess(listVno);
    }


    @GetMapping("/vehicleNo")
    public CoffeeResponse<List<String>> vehicleNumber(@RequestHeader("park") String park,
                                                      @RequestParam(name = "vno", required = false) String vno,
                                                      @RequestParam(name = "pole", required = false) String pole,
                                                      @RequestParam(name = "start", required = false) String start,
                                                      @RequestParam(name = "end", required = false) String end) {
        if (StrUtil.isEmpty(start) || StrUtil.isEmpty(end)) {
            return CoffeeResponse.response(CoffeeResponseEnum.ParamInvalid);
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime startDateTime = LocalDateTime.parse(start, formatter);
        LocalDateTime endDateTime = LocalDateTime.parse(end, formatter);
        long days = startDateTime.until(endDateTime, ChronoUnit.DAYS);
        if (days > 15) {
            return CoffeeResponse.responseMessage(CoffeeResponseEnum.ParamInvalid.code(), "时间间隔不能大于15天");
        }

        List<String> listVno = nezhaRecordService.listVehicleNo(park, vno, startDateTime, endDateTime);
        if (CollectionUtil.isEmpty(listVno)) {
            return CoffeeResponse.response(LatteResponseCode.ExcelNotData);
        }

        log.info("vehicleNo:   park {}, list size: {}", park, listVno.size());
        return CoffeeResponse.responseSuccess(listVno);
    }
    @GetMapping("/vehicle")
    public CoffeeResponse<List<VehicleVO>> vehicle(@RequestHeader("park") String park,
                                                      @RequestParam(name = "vno", required = false) String vno,
                                                      @RequestParam(name = "pole", required = false) String pole,
                                                      @RequestParam(name = "start", required = false) String start,
                                                      @RequestParam(name = "end", required = false) String end) {
        if (StrUtil.isEmpty(start) || StrUtil.isEmpty(end)) {
            return CoffeeResponse.response(CoffeeResponseEnum.ParamInvalid);
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime startDateTime = LocalDateTime.parse(start, formatter);
        LocalDateTime endDateTime = LocalDateTime.parse(end, formatter);
        long days = startDateTime.until(endDateTime, ChronoUnit.DAYS);
        if (days > 7) {
            return CoffeeResponse.responseMessage(CoffeeResponseEnum.ParamInvalid.code(), "时间间隔不能大于7天");
        }

        List<VehicleVO> listVno = nezhaRecordService.listTrackVehicle(park, vno, startDateTime, endDateTime);
        if (CollectionUtil.isEmpty(listVno)) {
            return CoffeeResponse.response(LatteResponseCode.ExcelNotData);
        }

        ParkDeviceBuilder builder = NezhaDeviceManager.getInstance().getBuilderData();
        Map<String, String> typeMap = null == builder ? null : builder.getVtypeMap();
        if (CollectionUtil.isNotEmpty(typeMap)){
             for (VehicleVO vehicleVO : listVno){
                 vehicleVO.setType(Optional.ofNullable(typeMap.get(vehicleVO.getVno())).orElse("1"));
             }
        }

//        Collections.reverse(listVno);
        listVno.sort((d1, d2) -> d2.getDate().compareTo(d1.getDate()));
        for (VehicleVO vo : listVno){
            vo.setDate(null);
        }
        log.info("vehicleNo:   park {}, list size: {}", park, listVno.size());
        return CoffeeResponse.responseSuccess(listVno);
    }
    @GetMapping("/vehicle-page")
    public CoffeeResponse<VehiclePage> vehiclePage(@RequestHeader("park") String park,
                                                       @RequestParam(name = "type", required = false) String type,
                                                       @RequestParam(name = "current", required = false) Integer current,
                                                       @RequestParam(name = "size", required = false) Integer size,
                                                      @RequestParam(name = "vno", required = false) String vno,
                                                      @RequestParam(name = "start", required = false) String start,
                                                      @RequestParam(name = "end", required = false) String end) {
        if (StrUtil.isEmpty(start) || StrUtil.isEmpty(end)) {
            return CoffeeResponse.response(CoffeeResponseEnum.ParamInvalid);
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime startDateTime = LocalDateTime.parse(start, formatter);
        LocalDateTime endDateTime = LocalDateTime.parse(end, formatter);
        long days = startDateTime.until(endDateTime, ChronoUnit.DAYS);
        if (days > 7) {
            return CoffeeResponse.responseMessage(CoffeeResponseEnum.ParamInvalid.code(), "时间间隔不能大于7天");
        }

        List<VehicleVO> listVno = nezhaRecordService.listTrackVehicle(park, vno, startDateTime, endDateTime);
        if (CollectionUtil.isEmpty(listVno)) {
            return CoffeeResponse.response(LatteResponseCode.ExcelNotData);
        }

        ParkDeviceBuilder builder = NezhaDeviceManager.getInstance().getBuilderData();
        Map<String, String> typeMap = null == builder ? null : builder.getVtypeMap();
        if (CollectionUtil.isNotEmpty(typeMap)){
             for (VehicleVO vehicleVO : listVno){
                 vehicleVO.setType(Optional.ofNullable(typeMap.get(vehicleVO.getVno())).orElse("1"));
             }
        }

//        Collections.reverse(listVno);
        listVno.sort((d1, d2) -> d2.getDate().compareTo(d1.getDate()));
        for (VehicleVO vo : listVno){
            vo.setDate(null);
        }
        log.info("vehicleNo:   park {}, list size: {}", park, listVno.size());
        return CoffeeResponse.responseSuccess(buildPage(listVno, type, current, size));
    }

    @GetMapping("/vehicle-online")
    public CoffeeResponse<List<VehicleVO>> vehicleOnline(@RequestHeader("park") String park,
                                                      @RequestParam(name = "vno", required = false) String vno,
                                                      @RequestParam(name = "pole", required = false) String pole,
                                                      @RequestParam(name = "start", required = false) String start,
                                                      @RequestParam(name = "end", required = false) String end) {

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        LocalDateTime startDateTime;
        LocalDateTime endDateTime;
        if (StrUtil.isNotEmpty(start) && StrUtil.isNotEmpty(end)){
            startDateTime = LocalDateTime.parse(start, formatter);
            endDateTime = LocalDateTime.parse(end, formatter);
            long days = startDateTime.until(endDateTime, ChronoUnit.DAYS);
            if (days > 7) {
                return CoffeeResponse.responseMessage(CoffeeResponseEnum.ParamInvalid.code(), "时间间隔不能大于7天");
            }
        }else {
            endDateTime = LocalDateTime.now();
            startDateTime = endDateTime.minusHours(24);
        }

        List<VehicleVO> listVno = nezhaRecordService.listTrackVehicleOnline(park, vno, startDateTime, endDateTime);
        if (CollectionUtil.isEmpty(listVno)) {
            return CoffeeResponse.response(LatteResponseCode.ExcelNotData);
        }

        ParkDeviceBuilder builder = NezhaDeviceManager.getInstance().getBuilderData();
        Map<String, String> typeMap = null == builder ? null : builder.getVtypeMap();
        if (CollectionUtil.isNotEmpty(typeMap)){
             for (VehicleVO vehicleVO : listVno){
                 vehicleVO.setType(Optional.ofNullable(typeMap.get(vehicleVO.getVno())).orElse("1"));
             }
        }

//        Collections.reverse(listVno);
        listVno.sort((d1, d2) -> d2.getDate().compareTo(d1.getDate()));
        for (VehicleVO vo : listVno){
            vo.setDate(null);
        }
        log.info("vehicleNo:   park {}, list size: {}", park, listVno.size());
        return CoffeeResponse.responseSuccess(listVno);
    }
    @GetMapping("/vehicle-online-page")
    public CoffeeResponse<VehiclePage> vehicleOnlinePage(@RequestHeader("park") String park,
                                                              @RequestParam(name = "type", required = false) String type,
                                                              @RequestParam(name = "current", required = false) Integer current,
                                                              @RequestParam(name = "size", required = false) Integer size,
                                                              @RequestParam(name = "vno", required = false) String vno,
                                                              @RequestParam(name = "start", required = false) String start,
                                                              @RequestParam(name = "end", required = false) String end) {

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime startDateTime;
        LocalDateTime endDateTime;
        if (StrUtil.isNotEmpty(start) && StrUtil.isNotEmpty(end)){
            startDateTime = LocalDateTime.parse(start, formatter);
            endDateTime = LocalDateTime.parse(end, formatter);
            long days = startDateTime.until(endDateTime, ChronoUnit.DAYS);
            if (days > 7) {
                return CoffeeResponse.responseMessage(CoffeeResponseEnum.ParamInvalid.code(), "时间间隔不能大于7天");
            }
        }else {
            endDateTime = LocalDateTime.now();
            startDateTime = endDateTime.minusHours(24);
        }

        List<VehicleVO> listVno = nezhaRecordService.listTrackVehicleOnline(park, vno, startDateTime, endDateTime);
        if (CollectionUtil.isEmpty(listVno)) {
            return CoffeeResponse.response(LatteResponseCode.ExcelNotData);
        }

        ParkDeviceBuilder builder = NezhaDeviceManager.getInstance().getBuilderData();
        Map<String, String> typeMap = null == builder ? null : builder.getVtypeMap();
        if (CollectionUtil.isNotEmpty(typeMap)){
             for (VehicleVO vehicleVO : listVno){
                 vehicleVO.setType(Optional.ofNullable(typeMap.get(vehicleVO.getVno())).orElse("1"));
             }
        }

//        Collections.reverse(listVno);
        listVno.sort((d1, d2) -> d2.getDate().compareTo(d1.getDate()));
        for (VehicleVO vo : listVno){
            vo.setDate(null);
        }
        log.info("vehicleNo:   park {}, list size: {}", park, listVno.size());

        return CoffeeResponse.responseSuccess(buildPage(listVno, type, current, size));
    }

    private VehiclePage buildPage(List<VehicleVO> listVno, String type, Integer current, Integer size){
        size = null == size  || 0 == size ? 5 : size;
        current = null == current ? 1 : current;

        Map<String, List<VehicleVO>> map = listVno.stream().collect(Collectors.groupingBy(VehicleVO::getType));
        VehiclePage vehiclePage = new VehiclePage();
        type = StrUtil.isEmpty(type) ? "0" : type;
        switch (type){
            case "1" : vehiclePage.setCar(buildList(map.get("1"), current, size)); break;
            case "3" : vehiclePage.setWhc(buildList(map.get("3"), current, size)); break;
            case "4" : vehiclePage.setWfc(buildList(map.get("4"), current, size)); break;
            default:
                vehiclePage.setCar(buildList(map.get("1"), current, size));
                vehiclePage.setWhc(buildList(map.get("3"), current, size));
                vehiclePage.setWfc(buildList(map.get("4"), current, size));
        }
        return vehiclePage;
    }

    // 应急处理； 以后花点时间处理
    // later forever
    private CoffeePage<VehicleVO> buildList(List<VehicleVO> list, int current, int size){
        if (CollectionUtil.isEmpty(list)){
            return null;
        }
        CoffeePage<VehicleVO> page = new CoffeePage<>();
        int fromIndex = (current - 1) * size;
        int toIndex = Math.min(fromIndex + size, list.size());
        if (fromIndex > list.size()) {
            return null;
        }
        page.setCurrent((long) current);
        page.setSize((long) size);
//        page.setTotal((long) list.size());
        page.setTotal((long) (( list.size() + size - 1) / size));
        page.setRecords(list.subList(fromIndex, toIndex));
        return page;
    }


    @GetMapping("/history-track")
    public CoffeeResponse<List<VehiclePathMessage>> historyTrackOnline(@RequestHeader("park") String park,
                                                                 @RequestParam(name = "vno") String vno,
                                                                 @RequestParam(name = "start", required = false) String startTime,
                                                                 @RequestParam(name = "end", required = false) String endTime) {

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime startDateTime;
        LocalDateTime endDateTime;
        if (StrUtil.isNotEmpty(startTime) && StrUtil.isNotEmpty(endTime)){
            startDateTime = LocalDateTime.parse(startTime, formatter);
            endDateTime = LocalDateTime.parse(endTime, formatter);
            long days = startDateTime.until(endDateTime, ChronoUnit.DAYS);
            if (days > 7) {
                return CoffeeResponse.responseMessage(CoffeeResponseEnum.ParamInvalid.code(), "时间间隔不能大于7天");
            }else if (days < 1){
                startDateTime = endDateTime.minusDays(7);
            }
        }else {
            endDateTime = LocalDateTime.now();
            startDateTime = endDateTime.minusDays(7);
        }
        try {
            return vehicleTrackService.historyTrackOnline(startDateTime, endDateTime, park, vno);
        } catch (CoffeeException e) {
            log.error("historyTrack Exception", e);
            return CoffeeResponse.response(e.getState());
        } catch (Exception e) {
            log.error("historyTrack Exception", e);
            return CoffeeResponse.response(CoffeeResponseEnum.SysException);
        }

    }

    //每个轨迹的详细数据
    @GetMapping("/historyTrack")
    public CoffeeResponse<List<VehiclePathMessage>> historyTrackTime(@RequestHeader("park") String park,
                                                                 @RequestParam(name="vno") String vno,
                                                                 @RequestParam(name = "start", required = false) String startTime,
                                                                 @RequestParam(name = "end", required = false) String endTime) {
        if (StrUtil.isEmpty(startTime) || StrUtil.isEmpty(endTime)) {
            return CoffeeResponse.response(CoffeeResponseEnum.ParamInvalid);
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime startDateTime = LocalDateTime.parse(startTime, formatter);
        LocalDateTime endDateTime = LocalDateTime.parse(endTime, formatter);
        long days = startDateTime.until(endDateTime, ChronoUnit.DAYS);
        if (days > 7) {
            return CoffeeResponse.responseMessage(CoffeeResponseEnum.ParamInvalid.code(), "时间间隔不能大于7天");
        }

        try {
            return vehicleTrackService.historyTrack(startDateTime, endDateTime, park, vno);
        } catch (CoffeeException e) {
            log.error("historyTrack Exception", e);
            return CoffeeResponse.response(e.getState());
        } catch (Exception e) {
            log.error("historyTrack Exception", e);
            return CoffeeResponse.response(CoffeeResponseEnum.SysException);
        }
    }
    @GetMapping("/track-stream")
    public CoffeeResponse<List<VehicleTrackStreamVO>> historyTrackStream(@RequestHeader("park") String park,
                                                                         @RequestParam("vno") String vno,
                                                                         @RequestParam(name = "start", required = false) String startTime,
                                                                         @RequestParam(name = "end", required = false) String endTime){
        if (StrUtil.isEmpty(startTime) || StrUtil.isEmpty(endTime)) {
            return CoffeeResponse.response(CoffeeResponseEnum.ParamInvalid);
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime startDateTime = LocalDateTime.parse(startTime, formatter);
        LocalDateTime endDateTime = LocalDateTime.parse(endTime, formatter);
        long days = startDateTime.until(endDateTime, ChronoUnit.DAYS);
        if (days > 7) {
            return CoffeeResponse.responseMessage(CoffeeResponseEnum.ParamInvalid.code(), "时间间隔不能大于7天");
        }

        try {
            startDateTime = startDateTime.minusMinutes(RandomUtil.randomInt(5, 9));
            endDateTime = endDateTime.plusMinutes(RandomUtil.randomInt(3, 9));
            List<VehicleTrackStreamVO> list = vehicleTrackService.findTrackStream(startDateTime, endDateTime, park, vno);
            if (CollectionUtil.isEmpty(list)) {
                return CoffeeResponse.response(LatteResponseCode.ExcelNotData);
            }
            return CoffeeResponse.responseSuccess(list);
        } catch (CoffeeException e) {
            log.error("historyTrack Exception", e);
            return CoffeeResponse.response(e.getState());
        } catch (Exception e) {
            log.error("historyTrack Exception", e);
            return CoffeeResponse.response(CoffeeResponseEnum.SysException);
        }

    }


    // 车辆流数据 -- 流媒体
    @GetMapping("/historyStream")
    public CoffeeResponse<List<StreamDataResponse>> historyStream(@RequestHeader("park") String park,
                                                                  @RequestParam("vno") String vno,
                                                                  @RequestParam(name = "start", required = false) String startTime,
                                                                  @RequestParam(name = "end", required = false) String endTime) {

        if (StrUtil.isEmpty(startTime) || StrUtil.isEmpty(endTime)) {
            return CoffeeResponse.response(CoffeeResponseEnum.ParamInvalid);
        }
        ParkPGEntity parkEntity = NezhaPersonManager.getInstance().parkPGEntity(park);
        if (null == parkEntity){
            log.error("historyStream handler>> park  null; park: {}", park);
            return CoffeeResponse.response(LatteResponseCode.ParamInvalid);
        }

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime startDateTime = LocalDateTime.parse(startTime, formatter);
        LocalDateTime endDateTime = LocalDateTime.parse(endTime, formatter);
        long days = startDateTime.until(endDateTime, ChronoUnit.DAYS);
        if (days > 7) {
            return CoffeeResponse.responseMessage(CoffeeResponseEnum.ParamInvalid.code(), "时间间隔不能大于7天");
        }

        List<VehicleTrackRecordPGEntity> list = nezhaRecordService.listTrackRecord(park, vno, startDateTime, endDateTime);
        if (CollectionUtil.isEmpty(list)) {
            log.info("historyStream: history data is null, vno: {}", vno);
            return CoffeeResponse.response(LatteResponseCode.ExcelNotData);
        }
        Set<String> cs = list.stream().map(VehicleTrackRecordPGEntity::getCameraCode).collect(Collectors.toSet());
        List<StreamDataRequest> sl = new ArrayList<>(cs.size());
        long st = startDateTime.toEpochSecond(ZoneOffset.of("+8"));
        long et = endDateTime.toEpochSecond(ZoneOffset.of("+8"));
        int i = 1;
        for (String c : cs) {
            sl.add(new StreamDataRequest(i, c, st, et));
            ++i;
        }

        StreamResponse response = OkhttpUtil.doPostStream(new StreamRequest(sl), parkEntity.getStreamUrl());
        if (null == response || CollectionUtil.isEmpty(response.getData())){
            log.info("historyStream: post data is null: park: {} vno: {}", park, vno);
            return CoffeeResponse.response(LatteResponseCode.ExcelNotData);
        }

        return CoffeeResponse.responseSuccess(response.getData());
    }

    //摄像头流
    @GetMapping("/history-stream")
    public LatteResponse<List<StreamDataResponse>> historyStreamByCamera(@RequestHeader("park") String park,
                                                                          @RequestParam("cno") String cno,
                                                                  @RequestParam(name = "start") String startTime,
                                                                  @RequestParam(name = "end") String endTime) {


        ParkPGEntity parkEntity = NezhaPersonManager.getInstance().parkPGEntity(park);
        if (null == parkEntity || StrUtil.isEmpty(parkEntity.getStreamUrl())){
            log.error("historyStream handler>> park  null; park: {}", park);
            return LatteResponse.response(LatteResponseCode.ParamInvalid);
        }

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime startDateTime = LocalDateTime.parse(startTime, formatter);
        LocalDateTime endDateTime = LocalDateTime.parse(endTime, formatter);
        long days = startDateTime.until(endDateTime, ChronoUnit.HOURS);
        if (days > 3) {
            List<StreamDataResponse> list = new ArrayList<>();
            LocalDateTime tempEnd;
            boolean isDo = true;
            while (isDo){
                tempEnd = startDateTime.plusHours(2);
                if (endDateTime.isBefore(tempEnd)){
                    isDo = false;
                    tempEnd = endDateTime;
                }
                if (!startDateTime.isEqual(tempEnd)){
                    List<StreamDataResponse> sl = OkhttpUtil.pullStreamByTime(startDateTime, tempEnd, cno, parkEntity, park);
                    if (CollectionUtil.isNotEmpty(sl)){
                        list.addAll(sl);
                    }
                }
                startDateTime = tempEnd;

            }

            if (CollectionUtil.isEmpty(list)){
                return LatteResponse.responseSuccess(null);
            }

            return LatteResponse.responseSuccess(list);
        }

        List<StreamDataResponse> list = OkhttpUtil.pullStreamByTime(startDateTime, endDateTime, cno, parkEntity, park);
        if (CollectionUtil.isEmpty(list)){
            return LatteResponse.responseSuccess(null);
        }

        return LatteResponse.responseSuccess(list);

    }

    @GetMapping("/screenshot-stream")
    public ResponseEntity<byte[]> screenshotStream(@RequestHeader("park") String park,
                                                     @RequestParam(name = "cno", required = false) String cno,
                                                     @RequestParam(name = "surl", required = false) String surl) {
        ParkPGEntity parkEntity = NezhaPersonManager.getInstance().parkPGEntity(park);
        if (null == parkEntity || StrUtil.isEmpty(parkEntity.getStreamUrl())){
            log.error("historyStream handler>> park  null; park: {}", park);
            return ResponseEntity.status(HttpStatus.PRECONDITION_REQUIRED).build();
        }
        if (StrUtil.isEmpty(cno) && StrUtil.isEmpty(surl)){
            log.error("historyStream handler>> param is  null");
            return ResponseEntity.status(HttpStatus.PRECONDITION_REQUIRED).build();
        }

        byte[] bytes = OkhttpUtil.findScreenshot(new ScreenshotRequest(cno, surl), park, parkEntity.getStreamUrl());
        if (null != bytes){
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.IMAGE_JPEG);
            headers.setContentLength(bytes.length);
            return ResponseEntity.ok()
                    .headers(headers)
                    .body(bytes);
        }
        return ResponseEntity.status(HttpStatus.PRECONDITION_REQUIRED).build();
    }



    // 车辆 经过的摄像头 所有 流数据 -- 流媒体，使用场景：WC
    @GetMapping("/vehicle-stream")
    public CoffeeResponse<List<StreamDataVO>> vehicleStream(@RequestHeader("park") String park,
                                                                  @RequestParam("vno") String vno,
                                                                  @RequestParam(name = "start") String startTime,
                                                                  @RequestParam(name = "end") String endTime) {
        ParkPGEntity parkEntity = NezhaPersonManager.getInstance().parkPGEntity(park);
        if (null == parkEntity){
            log.error("historyStream handler>> park  null; park: {}", park);
            return CoffeeResponse.response(LatteResponseCode.ParamInvalid);
        }

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime startDateTime = LocalDateTime.parse(startTime, formatter);
        LocalDateTime endDateTime = LocalDateTime.parse(endTime, formatter);
        long days = startDateTime.until(endDateTime, ChronoUnit.DAYS);
        if (days > 15) {
            return CoffeeResponse.responseMessage(CoffeeResponseEnum.ParamInvalid.code(), "时间间隔不能大于15天");
        }

       List<StreamDataVO> list = vehicleTrackService.vehicleStream(park, vno, startDateTime, endDateTime);
        if (CollectionUtil.isEmpty(list)){
            log.info("historyStream: history data is null, vno: {}", vno);
            return CoffeeResponse.response(LatteResponseCode.ExcelNotData);
        }

        return CoffeeResponse.responseSuccess(list);
    }
    @GetMapping("/camera-stream")
    public CoffeeResponse<StreamDataVO> vehicleStream(@RequestHeader("park") String park,
                                                            @RequestParam("cno") String cno,
                                                            @RequestParam(name = "timestamp") Long timestamp) {
        ParkPGEntity parkEntity = NezhaPersonManager.getInstance().parkPGEntity(park);
        if (null == parkEntity){
            log.error("historyStream handler>> park  null; park: {}", park);
            return CoffeeResponse.response(LatteResponseCode.ParamInvalid);
        }
        if (timestamp < 1){
            return CoffeeResponse.response(LatteResponseCode.ParamInvalid);
        }

        long st = timestamp > 10000000000L ? timestamp/1000 : timestamp;
        long et = st + 10;
        List<StreamDataResponse> list = OkhttpUtil.pullStream(cno, st-10, et, parkEntity.getStreamUrl(), park);
        if (CollectionUtil.isEmpty(list)){
            return null;
        }
        StreamDataVO streamDataVO = new StreamDataVO();
        streamDataVO.setPath(list.get(0).getPath());
        streamDataVO.setCno(cno);
        streamDataVO.setStartTime(StringKits.timeSToString(st));
        streamDataVO.setEndTime(StringKits.timeSToString(et));

        return CoffeeResponse.responseSuccess(streamDataVO);

    }


/*

    private List<VehiclePathMessage> doHistoryTrack(LocalDateTime startTime, LocalDateTime endTime, String park, String vno) throws CoffeeException {
        List<VehicleTrackRecordPGEntity> list = nezhaRecordService.listTrackRecord(park, vno, startTime, endTime);
        if (CollectionUtil.isEmpty(list)) {
            log.info("vehicleTrack: history data is null, vno: {}", vno);
            throw new CoffeeException(LatteResponseCode.ExcelNotData);
        }
        int size = list.size();
        List<VehiclePathMessage> dataList = new ArrayList<>();

        if (size < 3) {
            VehiclePathMessage message = buildPathMessage(park, vno, list);
            if (null == message) {
                throw new CoffeeException(LatteResponseCode.ExcelNotData);
            }
            dataList.add(message);
            return dataList;
        }


        List<VehicleTrackRecordPGEntity> temp = new ArrayList<>();
        for (int i = 0; i < size - 1; i++) {
            VehicleTrackRecordPGEntity current = list.get(i);
            listAdd(temp, current);
            VehicleTrackRecordPGEntity next = list.get(i + 1);
            long betweenHours = Math.abs(LocalDateTimeUtil.between(current.getAddTime(), next.getAddTime(), ChronoUnit.HOURS));
            if (betweenHours > 1) {
                VehiclePathMessage message = buildPathMessage(park, vno, temp);
                if (null != message) {
                    dataList.add(message);
                }
                temp.clear();
            } else {
                listAdd(temp, next);
            }
        }

        VehiclePathMessage message = buildPathMessage(park, vno, temp);
        if (null != message) {
            dataList.add(message);
        }

        return dataList;
    }*/
/*

    private void listAdd(List<VehicleTrackRecordPGEntity> temp, VehicleTrackRecordPGEntity trackRecordDTO) {
        for (VehicleTrackRecordPGEntity dto : temp) {
            if (dto.getId().equals(trackRecordDTO.getId())) {
                return;
            }
        }
        temp.add(trackRecordDTO);
    }

    private VehiclePathMessage buildPathMessage(String park, String vno, List<VehicleTrackRecordPGEntity> trackList) {
        if (CollectionUtil.isEmpty(trackList)) {
            return null;
        }

        int size = trackList.size();
        VehicleTrackRecordPGEntity startTrack = trackList.get(0);
        VehicleBO vehicleBO = new VehicleBO();
        vehicleBO.setVehicleNo(vno);
        vehicleBO.setType(startTrack.getVehicleType());
        VehiclePathMessage message = new VehiclePathMessage();
        message.setVehicleId(vehicleBO.getObjectId());
        message.setVehicleNo(vehicleBO.getVehicleNo());
        message.setType(vehicleBO.getType());
        message.setStartTime(DateUtil.formatLocalDateTime(startTrack.getAddTime()));
        if (size == 1) {
            message.setEndTime(message.getStartTime());
            return computePoint(message, park, startTrack);
        }

        VehicleTrackRecordPGEntity endTrack = trackList.get(size - 1);
        message.setEndTime(DateUtil.formatLocalDateTime(endTrack.getAddTime()));

        boolean isSame = true;
        for (VehicleTrackRecordPGEntity dto : trackList) {
            if (!dto.getPoleCode().equals(startTrack.getPoleCode())) {
                isSame = false;
                break;
            }
        }

        if (isSame || startTrack.getPoleCode().equals(endTrack.getPoleCode())) {
            return computePoint(message, park, startTrack);
        }

        PoleVertex startPole = NezhaDeviceManager.getInstance().getPoleVertexByPoleCode(park, startTrack.getPoleCode(), startTrack.getPoleLab());
        PoleVertex endPole = NezhaDeviceManager.getInstance().getPoleVertexByPoleCode(park, endTrack.getPoleCode(), endTrack.getPoleLab());
        if (null == startPole || null == endPole) {
            log.error("vehicleTrack:  startPole or endPole is null  | startPole: {}_{}, endPole: {}_{} ", startTrack.getPoleCode(), startTrack.getPoleLab(), endTrack.getPoleCode(), endTrack.getPoleLab());
            return computePoint(message, park, startTrack);
        }

        List<PoleVertex> vertexList = NezhaDeviceManager.getInstance().findVertexPaths(park, startPole, endPole);
        if (CollectionUtil.isEmpty(vertexList) || vertexList.size() == 1 || vertexList.size() > 300) {
            log.error("vehicleTrack:  data out of range or is null  | startPole: {}_{}, endPole: {}_{} ", startPole.getPoleCode(), startPole.getLab(), endPole.getPoleCode(), endPole.getLab());
            return computePoint(message, park, startTrack);
        }
        List<PoleEdge> edgeList = NezhaDeviceManager.getInstance().findEdgePaths(park, startPole, endPole);
        if (CollectionUtil.isEmpty(edgeList)) {
            log.error("vehicleTrack: vertexList not null but edgeList is null ; startPole: {}_{}, endPole: {}_{} ", startPole.getPoleCode(), startPole.getLab(), endPole.getPoleCode(), endPole.getLab());
            return computePoint(message, park, startTrack);
        }
        return computeLine(message, park, vertexList, edgeList, vehicleBO);
    }
*/


/*
    private VehiclePathMessage computePoint(VehiclePathMessage pathMessage, String park, VehicleTrackRecordPGEntity track) {
        PolePGEntity pgEntity = NezhaDeviceManager.getInstance().getPolePGEntityByPoleCode(park, track.getPoleCode());
        if (null == pgEntity) {
            return null;
        }

        List<PointMessage> list = new ArrayList<>(1);
        PointMessage pointMessage = new PointMessage();
        pointMessage.setLatitude(pgEntity.getXLat());
        pointMessage.setLongitude(pgEntity.getXLon());
        pointMessage.setHeight(pgEntity.getXHeight());
        pointMessage.setActTime(0);
        list.add(pointMessage);

        pathMessage.setPoint(1);
        pathMessage.setPoints(list);
        return pathMessage;
    }
*/

/*    private VehiclePathMessage computeLine(VehiclePathMessage pathMessage, String park, List<PoleVertex> vertexList, List<PoleEdge> edgeList, VehicleBO vehicleBO) {
        List<PointMessage> pointList = new ArrayList<>();
        for (PoleEdge edge : edgeList) {
            List<PointBO> pointBOList = edge.getPointList();
            if (CollectionUtil.isNotEmpty(pointBOList)) {
                for (PointBO bo : pointBOList) {
                    pointList.add(bo.buildMessage(vehicleBO.buildTime(bo.getT())));
                }
            }
        }

        pathMessage.setPoint(0);
        pathMessage.setPoints(pointList);
        return pathMessage;
    }*/

}
